import { PokerPoints } from "../constant/PokerPoints";
import { Poker } from "../data/Poker";

const { ccclass, property } = cc._decorator;

export type CardTouchCallback = (poker: Poker, isSelected: boolean) => void

/**
 * 卡牌控制类
 * 会被挂载到card预制体上
 * 实现触摸上升，和触摸事件通知
 */
@ccclass
export default class CardCtrl extends cc.Component {

    @property(cc.SpriteAtlas)
    cardSpriteAtlas: cc.SpriteAtlas = null

    public poker: Poker = null
    private isSelected = false
    private touchListeners: Set<Function | CardTouchCallback> = new Set()

    start() {

    }

    public set touchEnable(value: boolean) {
        if (value) {
            this.initTouchEvent()
        } else {
            this.offTouchEvent()
        }
    }

    public init(poker?: Poker): void {
        this.poker = poker
        this.initTouchEvent()
        if (this.poker) {
            this.show()
        }
    }

    /**
     * 显示牌面
     */
    private show(): void {
        const cardSprite = this.node.getComponent(cc.Sprite)
        let spriteFrameKey = 55   // 默认显示背面

        if (this.poker.point >= 1 && this.poker.point <= 13) {
            // 常规 1-13，即A~K
            spriteFrameKey = (this.poker.suit * 13) + this.poker.point
        } else if (this.poker.point == PokerPoints.P_BJ) {
            // 小王
            spriteFrameKey = 54
        } else if (this.poker.point == PokerPoints.P_RJ) {
            // 大王
            spriteFrameKey = 53
        }
        cardSprite.spriteFrame = this.cardSpriteAtlas.getSpriteFrame('card_' + spriteFrameKey)
    }

    /**
     * 显示背面
     */
    public showBack(): void {
        const cardSprite = this.node.getComponent(cc.Sprite)
        cardSprite.spriteFrame = this.cardSpriteAtlas.getSpriteFrame('card_55')
    }

    /**
     * 初始化卡牌触摸事件
     */
    private initTouchEvent() {
        this.node.on(cc.Node.EventType.TOUCH_START, this.onTouchEvent.bind(this))
    }

    private offTouchEvent() {
        this.node.off(cc.Node.EventType.TOUCH_START)
    }

    /**
     * 触摸事件
     * 设置卡片上升或下降
     */
    private onTouchEvent() {
        const distance = 20
        // 上升或下降
        if (this.isSelected) {
            // 下降
            cc.tween(this.node)
                .to(0.1, { y: 0 })
                .start()
        } else {
            // 上升
            cc.tween(this.node)
                .to(0.1, { y: distance })
                .start()
        }
        this.isSelected = !this.isSelected

        // 触发所有监听器
        this.touchListeners.forEach(callback => {
            callback(this.poker, this.isSelected)
        })
    }

    public addTouchListener(callback: Function | CardTouchCallback): Function {
        this.touchListeners.add(callback)
        return callback
    }

    public clearTouchListener(callback?: Function | CardTouchCallback) {
        if (callback == null) {
            // 清空所有监听器
            this.touchListeners.clear()
            return
        }
        this.touchListeners.delete(callback)
    }
}
